Skip to content

Conversation

@ye4241
Copy link
Contributor

@ye4241 ye4241 commented Dec 5, 2025

Changing the constructor of ServerSentEventsClient to public allows for complete customization of its construction and return process within a Controller. This eliminates the need to rely solely on the simpler dependency injection implementation.

For example:

public class SomeController: Controller
{
    public async Task SomeMethod()
    {
        this.Response.ContentType = "text/event-stream"; // or just MediaTypeNames.Text.EventStream
        var client = new ServerSentEventsClient(Guid.NewGuid(), this.HttpContext, true);
        await client.SendEventAsync("data: {\"key\": \"value\"}");
        await client.DisconnectAsync();
    }
}

It becomes much more convenient to control the entire SSE response.

@tpeczek
Copy link
Owner

tpeczek commented Dec 5, 2025

Hi @ye4241,

The sample you have provided is in general against the philosophy that this library has adopted and use case it aims to satisfy (that is closer to supporting Server-Sent Event broadcasting at scale, or in HTMX scenarios).

It looks rather like attempting to reuse one of its primitives to achieve completely different behaviour (handling Server-Sent Events requests one-by-one in controllers).

In the past I would be quite eager to consider this direction, but currently ASP.NET Core itself is handling that particular usecase very nicely with Minimal APIs. Below articles can be a good starting point for difference between the two:

@ye4241
Copy link
Contributor Author

ye4241 commented Dec 5, 2025

@tpeczek

The main reason I want to implement this is to create logic on an endpoint that dynamically evaluates the Accept header, similar to OpenAI's approach.

If the Accept header is set to text/event-stream, the endpoint should return results using Server-Sent Events (SSE).
On the other hand, if the header is set to application/json, it should directly return a JSON response.

@tpeczek
Copy link
Owner

tpeczek commented Dec 5, 2025

@ye4241

Content negotiation is generally available with this library (for use cases that it supports) as the ServerSentEventsService middleware is not a terminal one for exactly that purpose.

You can register the middleware for a specific path (typically with UseWhen) - it will grab the requests with text/event-stream but different media types (like aplication/json) will be passed through and can be handled by a controller action on the same path.

For use cases that are better handled by the new ASP.NET Core 10 capabilities you can achieve similar there by checking the Accept header and returning different result types.

@ye4241
Copy link
Contributor Author

ye4241 commented Dec 7, 2025

@tpeczek Alright, if the constructor isn't made accessible, perhaps the only options are the two approaches mentioned above. Alternatively, using a using statement followed by construction might also be a good way to ensure automatic disposal.

@tpeczek
Copy link
Owner

tpeczek commented Dec 9, 2025

@ye4241 It is also possible that the .NET 10 has added the exact primitive you are looking for: https://devblogs.microsoft.com/dotnet/dotnet-10-networking-improvements/#server-sent-events-formatter

In general, I'm going to close this pull request as it pushes the library in unintended direction.

@ye4241 ye4241 closed this Dec 9, 2025
@ye4241
Copy link
Contributor Author

ye4241 commented Dec 9, 2025

Okay, I will try SSE with .NET 10.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants